package com.weishi.project.training.domain;

import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.weishi.common.utils.DateUtils;
import com.weishi.common.utils.GPSUtil;
import com.weishi.project.speedometer.vo.RealTimeDataVo;
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 船速仪历史数据
 */
@Data
@TableName("tbl_ship_speed_record_log")
public class ShipSpeedRecordLog implements Serializable {

    private static final long serialVersionUID = 1L;

    /** 船速仪表历史数据 */
    private Integer id;
    
    /** 船速仪id */
    private String shipSpeedSn;

    /**
     * 航道Id
     */
    private Integer channelId;

    /** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date ctime;
    
    /** 经度 */
    private double longitude;
    
    /** 纬度 */
    private double latitude;
    
    /** uct 时间 */
    private String utc;

    //数据转换(经纬度-距离)
    public static List<RealTimeDataVo> getRealTimeData(List<ShipSpeedRecordLog> list){
        list = dataFormat(list);

        boolean flag = true;//是否忽略为0的点，两个为零的点忽略一个

        List<RealTimeDataVo> retList = new ArrayList<>();
        //初始点
        Double lat1 = null;
        Double lng1 = null;
        Double time1 = 0.000;

        //上一点
        Double latbe = null;
        Double lngbe = null;
        Double timebe = 0.000;
        double totalDistance = 0.000;
        double totalTime = 0.00;

        int len = 0; //5个点取一次
        int intervalNumber = 1; //取值因子

        for(ShipSpeedRecordLog shipSpeedRecordLog : list){
            RealTimeDataVo realTimeDataVo = new RealTimeDataVo();
            double latTemp = shipSpeedRecordLog.getLatitude();
            double lngTemp = shipSpeedRecordLog.getLongitude();
            String utc = shipSpeedRecordLog.getUtc()+"0";
            Date dateTime = DateUtils.dateTime("HHmmss.SSS",utc);
            double timeTemp = dateTime.getTime();

            if (lat1 == null) {
                lat1 = latTemp;
                lng1 = lngTemp;
                time1 = timeTemp;
                latbe = latTemp;
                lngbe = lngTemp;
                timebe = timeTemp;
                continue;
            }
            if(len++<intervalNumber){
                continue;
            }else{
                len=0;
            }

            double mmbe = GPSUtil.GetDistance1(latbe, lngbe, latTemp, lngTemp);
            if(mmbe==0 && flag){
                flag = false;
                latbe = latTemp;
                lngbe = lngTemp;
                timebe = timeTemp;
                //距离等于0米直接忽略
                continue;
            }else if(mmbe==0 && !flag){
                flag = true;
            }
            totalDistance += mmbe;
            double mm1 = GPSUtil.GetDistance1(lat1, lng1, latTemp, lngTemp);
            //realTimeDataVo.setDistanceTotal(totalDistance);
            realTimeDataVo.setDistanceTotal(totalDistance);
            realTimeDataVo.setStraightLineDistance(mm1);
            double speed = 0.0;
            if(timeTemp-timebe>0){
                //速度大于10m的点的直接忽略
                speed = (mmbe/((timeTemp-timebe)/1000));
                if(speed>10){
                    continue;
                }
                realTimeDataVo.setDistance(speed);
            }
            realTimeDataVo.setTime(timeTemp-timebe);
            totalTime = (timeTemp-time1)/1000;
            realTimeDataVo.setTimeTotal(totalTime);
            realTimeDataVo.setRealTime(DateUtils.parseDateToStr("HH:mm:ss.SSS",DateUtils.addHours(dateTime,8)));


            //刷新上个节点
            latbe = latTemp;
            lngbe = lngTemp;
            timebe = timeTemp;

            //累计距离和直线距离大于2m忽略
            /*if(totalDistance-mm1>2 || mm1-totalDistance>2){
                totalDistance = mm1;
                continue;
            }*/

            //瞬时速度与平均速度差3的时候忽略
            double averageVelocity = totalDistance/totalTime;
            if(averageVelocity-speed>5 || speed-averageVelocity>5){
                continue;
            }

            intervalNumber = getIntervalNumber(averageVelocity);

            retList.add(realTimeDataVo);
        }
        return retList;
    }

    /**
     * 数据格式化，将错误的点的数据去掉
     * 规则：每10个点作为一个标准纠错点
     * @param list
     * @return
     */
    private static List<ShipSpeedRecordLog> dataFormat(List<ShipSpeedRecordLog> list){
        if(list==null || list.size()==0){
            return list;
        }
        List<ShipSpeedRecordLog> temp = new ArrayList<>();
        ShipSpeedRecordLog fisrt = list.get(0);
        String utc = fisrt.getUtc()+"0";
        Date dateTime = DateUtils.dateTime("HHmmss.SSS",utc);

        //取10个点作为一个标准纠错点
        int step = 10;
        //初始点
        Double lat1 = fisrt.latitude;
        Double lng1 = fisrt.longitude;
        long time1 = dateTime.getTime();

        //上一点
        Double latbe = fisrt.latitude;
        Double lngbe = fisrt.longitude;
        double totalDistance = 0.000;

        for(ShipSpeedRecordLog shipSpeedRecordLog : list){
            utc = shipSpeedRecordLog.getUtc()+"0";
            dateTime = DateUtils.dateTime("HHmmss.SSS",utc);
            long timeInterval = dateTime.getTime()-time1;

            double mmbe = GPSUtil.GetDistance1(latbe, lngbe, shipSpeedRecordLog.getLatitude(), shipSpeedRecordLog.getLongitude());
            if(mmbe==0){
                latbe = shipSpeedRecordLog.getLatitude();
                lngbe = shipSpeedRecordLog.getLongitude();
                //距离等于0米直接忽略
                continue;
            }
            totalDistance += mmbe;
            double mm1 = GPSUtil.GetDistance1(lat1, lng1, shipSpeedRecordLog.getLatitude(), shipSpeedRecordLog.getLongitude());
            latbe = shipSpeedRecordLog.getLatitude();
            lngbe = shipSpeedRecordLog.getLongitude();

            //累计距离和直线距离大于2m忽略
            if((totalDistance-mm1)/(timeInterval/1000)>10 || (mm1-totalDistance)/(timeInterval/1000)>10){
                totalDistance = mm1;
                continue;
            }
            temp.add(shipSpeedRecordLog);
            //刷新上个节点
            latbe = shipSpeedRecordLog.getLatitude();
            lngbe = shipSpeedRecordLog.getLongitude();
        }
        return temp;
    }

    /**
     * 根据平均速度，获取取值间隔因子
     * @return
     */
    private static int getIntervalNumber(double averageVelocity){
        int intervalNumber = 0;
        if(averageVelocity<2){
            intervalNumber = 3;
        }else if(averageVelocity<3){
            intervalNumber = 2;
        }else{
            intervalNumber = 1;
        }
        return intervalNumber;
    }

}